home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Utilities / Workspace / WrapperInspector / Source / WrapperInspector.m < prev    next >
Text File  |  1995-06-12  |  9KB  |  340 lines

  1. //----------------------------------------------------------------------------------------------------
  2. //
  3. //    WrapperInspector
  4. //
  5. //    Inherits From:        Object
  6. //
  7. //    Declared In:        WrapperInspector.h
  8. //
  9. //    Disclaimer
  10. //
  11. //        You may freely copy, distribute and reuse this software and its
  12. //        associated documentation. I disclaim any warranty of any kind, 
  13. //        expressed or implied, as to its fitness for any particular use.
  14. //
  15. //----------------------------------------------------------------------------------------------------
  16. #import "WrapperInspector.h"
  17. #import "DefaultSubInspector.h"
  18. #import <objc/objc-runtime.h>
  19. #import <bsd/sys/dir.h>
  20.  
  21.  
  22. @implementation WrapperInspector
  23.  
  24. static id     _SELF = nil;
  25.  
  26. //----------------------------------------------------------------------------------------------------
  27. //  WMInspector Methods
  28. //----------------------------------------------------------------------------------------------------
  29. + new
  30. {
  31.     //  Required/called by WM.  Only allow one instance...
  32.     
  33.         char     path[MAXPATHLEN+1];
  34.         id         bundle;
  35.  
  36.         if (_SELF) return _SELF;
  37.  
  38.         _SELF = self = [super new];
  39.  
  40.         if ( ! (bundle = [NXBundle bundleForClass: [WrapperInspector class]] ) ) return nil;          
  41.     if ( ! [bundle getPath: path forResource: "WrapperInspector" ofType: "nib"] ) return nil;
  42.         [NXApp loadNibFile: path owner: self  withNames: NO fromZone: [self zone]];
  43.  
  44.      [splitView addSubview: browser];
  45.     [splitView addSubview: inspectorView];
  46.     [splitView adjustSubviews];
  47.     [splitView display];
  48.     
  49.      return _SELF;
  50. }
  51.  
  52.  
  53. - revert: sender
  54. {
  55.     //  Called by WM when file selection is type we inspect or when 
  56.     //  'Open As Folder' button is pressed.
  57.     
  58.     if (sender == [self revertButton])
  59.         {
  60.         [self openAsFolder: nil];
  61.         return [super revert:sender];
  62.         }
  63.  
  64.     [[[[self okButton] setTitle: "Open"] setIconPosition: NX_TITLEONLY] setEnabled: YES];
  65.     [[[self revertButton] setTitle: "Open As Folder"] setEnabled: YES];
  66.  
  67.     [browser setDoubleAction: @selector(open:)];
  68.     [browser setTitle: [fileNameField stringValue] ofColumn: 0];
  69.     [browser loadColumnZero];
  70.     
  71.     if ([self isDirectory])
  72.         [self noInspector];
  73.     else
  74.         [self selectionNotADirectory];
  75.     
  76.     [self updateSubPath];
  77.  
  78.     [super revert: sender];
  79.     return self;
  80. }
  81.  
  82.  
  83. - ok: sender
  84. {
  85.     //  User pressed 'Open' button...
  86.     
  87.     [self open: nil];
  88.     return [super ok:sender];
  89. }
  90.  
  91.  
  92. //----------------------------------------------------------------------------------------------------
  93. //  Action Methods
  94. //----------------------------------------------------------------------------------------------------
  95. - fileSelected: sender
  96. {
  97.     //  Invoke inpector based on extension... Enable 'Open As Folder'
  98.     //  button if directory.  Update subPath display.
  99.     
  100.     STR            currentPath;
  101.     STR            extension;
  102.     const char*    inspectorClass;    
  103.  
  104.     [self updateSubPath];
  105.  
  106.     if (! (currentPath = [self currentPath])) return [self noInspector];
  107.     
  108.     if ([[browser selectedCell] isLeaf]) 
  109.         [[self revertButton] setEnabled: NO];
  110.     else
  111.         [[self revertButton] setEnabled: YES];
  112.         
  113.     if (! (extension = [self extension: currentPath]))
  114.         {
  115.         if (currentPath) free(currentPath);
  116.         return [self noInspector];
  117.         }
  118.  
  119.     if ((inspectorClass = [inspectorStrings valueForStringKey: extension]))
  120.         [self inspect: (STR)currentPath usingInspectorClass: (STR)inspectorClass];
  121.     else
  122.         [self noInspector];
  123.  
  124.     if (currentPath) free(currentPath);
  125.     if (extension) free(extension);
  126.     
  127.     return self;
  128. }
  129.  
  130.  
  131. - open: sender
  132. {
  133.     //  Open current selection in WM.
  134.  
  135.     STR        currentPath;
  136.     
  137.     if (! (currentPath = [self currentPath])) return NULL;
  138.     [[Application workspace] openFile:currentPath withApplication: NULL andDeactivate: NO];
  139.     if (currentPath) free(currentPath);
  140.     return self;
  141. }
  142.     
  143.     
  144. - openAsFolder: sender
  145. {
  146.     //  Open current selection as folder in WM.
  147.  
  148.     STR        currentPath;
  149.     
  150.     if (! (currentPath = [self currentPath])) return NULL;
  151.     [[Application workspace] selectFile:currentPath inFileViewerRootedAt:currentPath];
  152.     if (currentPath) free(currentPath);
  153.     return self;
  154. }
  155.     
  156.     
  157. //----------------------------------------------------------------------------------------------------
  158. //  Inspection Methods
  159. //----------------------------------------------------------------------------------------------------
  160. - inspect: (STR)currentPath usingInspectorClass: (STR)inspectorClass
  161. {
  162.     //  Get the Class ID for the specified subinspector and send it the
  163.     //  message 'new' to create an instance.  If successful, message 
  164.     //  the instance for its inspectorView and to inspect the current path.
  165.     
  166.     id        inspector;
  167.     Class      inspectorClassID = objc_lookUpClass(inspectorClass);
  168.     
  169.     if ( ! inspectorClassID)  return [self noInspector];
  170.     
  171.     inspector = objc_msgSend ((id)inspectorClassID, @selector(new));
  172.     if ( ! inspector)  return [self noInspector];
  173.  
  174.     [inspectorView setContentView: [inspector inspectorView]];
  175.     [inspectorView display];
  176.     
  177.     [inspector inspect: currentPath];
  178.     
  179.     return self;
  180. }
  181.     
  182.  
  183. - noInspector
  184. {
  185.     //  No Inspector for this file type.
  186.     
  187.     [messageText setStringValue: "No Inspector"];
  188.     [inspectorView setContentView: [messageView contentView]];
  189.     [inspectorView display];
  190.     return self;
  191. }
  192.  
  193.  
  194. - selectionNotADirectory
  195. {
  196.     //  This for cases when WM selection has right extension, but is not
  197.     //  actually a directory (for example, some .nibs are not directories).
  198.     
  199.     [[self okButton] setEnabled: NO];
  200.     [[self revertButton] setEnabled: NO];
  201.     [messageText setStringValue: "Not A Directory"];
  202.     [inspectorView setContentView: [messageView contentView]];
  203.     [inspectorView display];
  204.     return self;
  205. }
  206.  
  207.  
  208. //----------------------------------------------------------------------------------------------------
  209. //  Selection Path Methods
  210. //----------------------------------------------------------------------------------------------------
  211. - (STR) currentPath
  212. {
  213.     //  Original WM selection path plus current browser path.  Caller must free.
  214.     
  215.     char     currentPath[MAXPATHLEN+1];
  216.     char     browserPath[MAXPATHLEN+1];
  217.  
  218.     [self selectionPathsInto:currentPath separator:'\0'];
  219.     
  220.     if ([browser selectedCell])
  221.         {
  222.         [browser getPath:browserPath toColumn: [browser selectedColumn]];
  223.         strcat (currentPath, browserPath);
  224.         strcat (currentPath, "/");
  225.         strcat (currentPath, [[browser selectedCell] stringValue]);
  226.         }
  227.     
  228.     return NXCopyStringBuffer (currentPath);
  229. }
  230.  
  231.  
  232. - (STR) extension: (const char*) path
  233. {
  234.     //  File's extension if found, pointer to NULL otherwise.  Caller must free.
  235.  
  236.     STR    start = (STR)path;
  237.     STR    end;
  238.  
  239.     for (end = (start + strlen(start) -1); end >= start; end--)
  240.         {
  241.         if (*end == '.') break;
  242.         if (*end == '/') return NULL;
  243.         }
  244.  
  245.     if ((end - start) == -1) return NULL;
  246.         
  247.     start += (end - start) + 1;
  248.     return NXCopyStringBuffer(start);
  249. }
  250.  
  251.  
  252. - (BOOL)isDirectory
  253. {
  254.     //  YES if current path is a directory...
  255.     
  256.     struct stat     statBuffer;
  257.     STR            currentPath = [self currentPath];
  258.  
  259.     if (! currentPath) return NO;
  260.     
  261.     stat (currentPath, &statBuffer); 
  262.     if (currentPath) free(currentPath);
  263.     if ( (statBuffer.st_mode & S_IFMT) != S_IFDIR)
  264.         return NO;
  265.         
  266.     return YES;
  267. }
  268.  
  269.  
  270. - updateSubPath
  271. {
  272.     //  Update subPath display...
  273.     
  274.     char     subPath[MAXPATHLEN+1];
  275.     char     browserPath[MAXPATHLEN+1];
  276.  
  277.     strcpy(subPath, [fileNameField stringValue]);
  278.  
  279.     if ([browser selectedCell])
  280.         {
  281.         [browser getPath:browserPath toColumn: [browser selectedColumn]];
  282.         strcat (subPath, browserPath);
  283.         strcat (subPath, "/");
  284.         strcat (subPath, [[browser selectedCell] stringValue]);
  285.         }
  286.  
  287.     [subPathText setStringValue: subPath];
  288.     return self;
  289. }
  290.  
  291.  
  292. //----------------------------------------------------------------------------------------------------
  293. //  Browser Delegate Method
  294. //----------------------------------------------------------------------------------------------------
  295. - (int) browser: aBrowser fillMatrix: aMatrix inColumn: (int)aColumn
  296. {
  297.     int            count = 0;
  298.     DIR*            directory;
  299.     STR         currentPath;
  300.     char         pathBuffer[MAXPATHLEN+1];
  301.     struct stat     statBuffer;
  302.     struct direct*    directoryPointer;
  303.  
  304.     currentPath = [self currentPath];
  305.         
  306.     if (! (directory = opendir(currentPath))) 
  307.         {
  308.         if (currentPath)  free(currentPath);
  309.         [self selectionNotADirectory];
  310.         return 0;
  311.         }
  312.     
  313.     for (directoryPointer = readdir(directory); directoryPointer != NULL; 
  314.             directoryPointer =  readdir(directory))
  315.         {
  316.         if (NXOrderStrings (directoryPointer->d_name, ".", YES, -1, NULL) == 0) continue;
  317.         if (NXOrderStrings (directoryPointer->d_name, "..", YES, -1, NULL) == 0) continue;
  318.  
  319.         [aMatrix renewRows: (count+1) cols: 1];
  320.         [[aMatrix cellAt: count :0] setStringValue: directoryPointer->d_name];
  321.         [[aMatrix cellAt: count :0] setLoaded: YES];
  322.         
  323.         strcpy (pathBuffer, currentPath);
  324.         strcat (pathBuffer, "/");
  325.         strcat (pathBuffer, directoryPointer->d_name);
  326.  
  327.         stat (pathBuffer, &statBuffer); 
  328.         if ( (statBuffer.st_mode & S_IFMT) != S_IFDIR)
  329.                 [[aMatrix cellAt: count :0] setLeaf:YES];
  330.             
  331.         count++;
  332.         }
  333.     
  334.     if (currentPath)  free(currentPath);
  335.     closedir(directory);
  336.     return count;
  337. }
  338.     
  339.  
  340. @end